/**
 * @addtogroup BAS
 * @{
 * @file
 * Vector容器操作
 */
#include <assert.h>
#include <string.h>
#include "bas/bas_vector.h"

static const char mcaId[] = "$Id$";

//重新分配内存策略: 当前值的两倍
#define _BAS_VECTOR_RESERVE(_ptVector) basVectorReserve(_ptVector, basVectorCapacity(_ptVector) * 2)

//判断Vector是否已满
#define _BAS_VECTOR_IS_FULL(_ptVector) ((_ptVector)->pvEndPos >= (_ptVector)->pvEndPosOfStorage)

static bool _basVectorIteratorIsValid(const T_Iterator tIterator);
static void _basVectorIteratorGetValue(const T_Iterator tIterator, void *pvValue);
static void *_basVectorIteratorGetPointer(const T_Iterator tIterator);
static void _basVectorIteratorSetValue(T_Iterator tIterator, const void * pvValue);
static T_Iterator _basVectorIteratorNext(const T_Iterator tIterator);
static T_Iterator _basVectorIteratorPrev(const T_Iterator tIterator);
static bool _basVectorIteratorEqual(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);
static bool _basVectorIteratorLess(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);
static T_Iterator _basVectorIteratorNextN(const T_Iterator tIterator, const size_t nCount);
static T_Iterator _basVectorIteratorPrevN(const T_Iterator tIterator, const size_t nCount);
static int _basVectorIteratorMinus(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);

//Vector迭代器回调函数表
static T_IteratorCallBackTable mtVectorIteratorCallBackTable =
    {_basVectorIteratorIsValid,
     _basVectorIteratorGetValue,
     _basVectorIteratorGetPointer,
     _basVectorIteratorSetValue,
     _basVectorIteratorNext,
     _basVectorIteratorPrev,
     _basVectorIteratorEqual,
     _basVectorIteratorLess,
     _basVectorIteratorNextN,
     _basVectorIteratorPrevN,
     _basVectorIteratorMinus};

BAS_EXPORT T_Vector *basVectorCreate(const T_TypeInfo tTypeInfo)
{
    T_Vector *ptVector = NULL;

    if (NULL == (ptVector = (T_Vector *)malloc(sizeof(T_Vector))))
    {
        CONTAINER_LOG_ERROR("malloc failed");
        return NULL;
    }
    memset(ptVector, 0, sizeof(T_Vector));

    //迭代器回调函数表
    ptVector->ptCallBackTable = &mtVectorIteratorCallBackTable;
    //类型信息
    memcpy(&ptVector->tTypeInfo, &tTypeInfo, sizeof(ptVector->tTypeInfo));

    //初始化Vector
    if (NULL == (ptVector->pvStartPos = 
                 (void *)malloc(ptVector->tTypeInfo.nTypeSize * VECTOR_INIT_SIZE)))
    {
        free(ptVector);
        CONTAINER_LOG_ERROR("malloc failed");
        return NULL;
    }
    ptVector->pvEndPos = ptVector->pvStartPos;
    ptVector->pvEndPosOfStorage = ptVector->pvStartPos + ptVector->tTypeInfo.nTypeSize * VECTOR_INIT_SIZE;

    return ptVector; 
}

BAS_EXPORT void basVectorDestroy(T_Vector *ptVector)
{
    if (NULL == ptVector)
    {
        return;
    }

    basVectorResize(ptVector, 0);
    free(ptVector->pvStartPos);
    free(ptVector);
}

BAS_EXPORT void basVectorClear(T_Vector *ptVector)
{
    assert(ptVector != NULL);

    basVectorResize(ptVector, 0);
}

BAS_EXPORT size_t basVectorSize(const T_Vector *ptVector)
{
    assert(ptVector != NULL);

    return (ptVector->pvEndPos - ptVector->pvStartPos) / ptVector->tTypeInfo.nTypeSize;
}

BAS_EXPORT int _basVectorResize(T_Vector *ptVector, const size_t nSize, ...)
{
    assert(ptVector != NULL);

    va_list varList;
    void *pvInitParameter = NULL;
    size_t nRemoveCnt = 0;
    size_t nAddCnt = 0;

    //如果nSize小于Vector中当前的元素个数, 
    //则舍弃除了前nSize以后的所有元素, 并且调用销毁函数(如果有的话)
    if (nSize < basVectorSize(ptVector))
    {
        nRemoveCnt = basVectorSize(ptVector) - nSize; 
        if (ptVector->tTypeInfo.pfnDestroy != NULL)
        {
            for (size_t i = 0; i < nRemoveCnt; ++i)
                basVectorPopBack(ptVector);
        }
        else
        {
            ptVector->pvEndPos -= ptVector->tTypeInfo.nTypeSize * nRemoveCnt;
        }

        return 0;
    }

    //如果nSize大于Vector的容量, 首先重新分配内存
    if (nSize > basVectorCapacity(ptVector)) 
    {
        if (basVectorReserve(ptVector, nSize) != 0)
        {
            CONTAINER_LOG_ERROR("basVectorReserve failed");
            return -1;
        }
    }

    //增加Vector的大小
    nAddCnt = nSize - basVectorSize(ptVector);
    ptVector->pvEndPos += ptVector->tTypeInfo.nTypeSize * nAddCnt; 

    //空白元素初始化
    //如果指定了初始化函数
    if (ptVector->tTypeInfo.pfnInit != NULL)
    {
        //取初始化参数    
        va_start(varList, nSize); 
        if (BAS_PARM_END == (pvInitParameter = va_arg(varList, void *)))
        {
            pvInitParameter = NULL;
        }
        va_end(varList);
        
        //调用初始化函数初始化
        for (int i = 1; i <= nAddCnt; ++i)
        {
            if (ptVector->tTypeInfo.pfnInit(basVectorAt(ptVector, -i), pvInitParameter) != 0)
            {
                CONTAINER_LOG_ERROR("pfnInit failed");
                return -1;
            }
        }
    }
    else
    {
        //默认全部填0
        memset(ptVector->pvEndPos - ptVector->tTypeInfo.nTypeSize * nAddCnt, 0,
               ptVector->tTypeInfo.nTypeSize * nAddCnt);
    }

    return 0;
}

BAS_EXPORT bool basVectorEmpty(const T_Vector *ptVector)
{
    assert(ptVector != NULL);

    return (basVectorSize(ptVector) == 0);
}

BAS_EXPORT size_t basVectorCapacity(const T_Vector *ptVector)
{
    assert(ptVector != NULL);

    return (ptVector->pvEndPosOfStorage - ptVector->pvStartPos) / ptVector->tTypeInfo.nTypeSize;
}

BAS_EXPORT int basVectorReserve(T_Vector *ptVector, const size_t nCapacity)
{
    assert(ptVector != NULL);

    size_t nVectorSize = basVectorSize(ptVector);

    if (nCapacity <= basVectorCapacity(ptVector))
    {
        return 0;
    }

    if (NULL ==
        (ptVector->pvStartPos = realloc(ptVector->pvStartPos, 
                                        ptVector->tTypeInfo.nTypeSize * nCapacity)))
    {
        CONTAINER_LOG_ERROR("realloc failed");
        return -1;
    }
    ptVector->pvEndPos = ptVector->pvStartPos + ptVector->tTypeInfo.nTypeSize * nVectorSize;
    ptVector->pvEndPosOfStorage = ptVector->pvStartPos + ptVector->tTypeInfo.nTypeSize * nCapacity;
    
    return 0;
}

BAS_EXPORT int basVectorPushBack(T_Vector *ptVector, ...)
{
    assert(ptVector != NULL);

    va_list varList;

    //Vector已满, 重新分配内存
    if (_BAS_VECTOR_IS_FULL(ptVector))
    {
        if (_BAS_VECTOR_RESERVE(ptVector) != 0)
        {
            CONTAINER_LOG_ERROR("basVectorReserve failed");
            return -1;
        }
    }

    //根据数据类型从可变参数取值
    va_start(varList, ptVector);
    if (_basContainerGetVaArgValue(&ptVector->tTypeInfo, ptVector->pvEndPos, &varList) != 0)
    {
        CONTAINER_LOG_ERROR("_basContainerGetVaArgValue failed");
        return -1;
    }
    va_end(varList);

    ptVector->pvEndPos += ptVector->tTypeInfo.nTypeSize;

    return 0;
}

BAS_EXPORT void basVectorPopBack(T_Vector *ptVector)
{
    assert(ptVector != NULL);

    if (basVectorEmpty(ptVector))
    {
        CONTAINER_LOG_WARN("vector is empty");
        return;
    }

    //调用销毁函数(如果有的话)
    if (ptVector->tTypeInfo.pfnDestroy != NULL)
    {
        (ptVector->tTypeInfo.pfnDestroy)(basVectorAt(ptVector, -1));
    }

    ptVector->pvEndPos -= ptVector->tTypeInfo.nTypeSize;
}

BAS_EXPORT void *basVectorAt(const T_Vector *ptVector, const int iIndex)
{
    assert(ptVector != NULL);

    int iInnerIndex = 0;

    if (basVectorEmpty(ptVector))
    {
        CONTAINER_LOG_ERROR("vector is empty");
        return NULL;
    }

    if (iIndex < 0)
    {
        iInnerIndex = basVectorSize(ptVector) + iIndex;
        if (iInnerIndex < 0) iInnerIndex = 0;
    }
    else
    {
        iInnerIndex = (iIndex > basVectorSize(ptVector) - 1) ? basVectorSize(ptVector) - 1 : iIndex;
    }

    return ptVector->pvStartPos + ptVector->tTypeInfo.nTypeSize * iInnerIndex;
}

BAS_EXPORT T_Iterator basVectorBegin(const T_Vector *ptVector)
{
    assert(ptVector != NULL);

    T_Iterator tIterator;

    tIterator.tPos.pvBasicPos = ptVector->pvStartPos;
    tIterator.pvContainer = (void *)ptVector;
    tIterator.eIteratorType = ITERATOR_RANDOM_ACCESS;
    tIterator.eContainerType = CONTAINER_VECTOR;

    return tIterator;
}

BAS_EXPORT T_Iterator basVectorEnd(const T_Vector *ptVector)
{
    assert(ptVector != NULL);

    T_Iterator tIterator;

    tIterator.tPos.pvBasicPos = ptVector->pvEndPos;
    tIterator.pvContainer = (void *)ptVector;
    tIterator.eIteratorType = ITERATOR_RANDOM_ACCESS;
    tIterator.eContainerType = CONTAINER_VECTOR;

    return tIterator;
}

BAS_EXPORT T_Iterator basVectorRBegin(const T_Vector *ptVector)
{
    assert(ptVector != NULL);

    T_Iterator tIterator;

    tIterator.tPos.pvBasicPos = ptVector->pvEndPos - ptVector->tTypeInfo.nTypeSize;
    tIterator.pvContainer = (void *)ptVector;
    tIterator.eIteratorType = ITERATOR_RANDOM_ACCESS;
    tIterator.eContainerType = CONTAINER_VECTOR;

    return tIterator;
}

BAS_EXPORT T_Iterator basVectorREnd(const T_Vector *ptVector)
{
    assert(ptVector != NULL);

    T_Iterator tIterator;

    tIterator.tPos.pvBasicPos = ptVector->pvStartPos - ptVector->tTypeInfo.nTypeSize;
    tIterator.pvContainer = (void *)ptVector;
    tIterator.eIteratorType = ITERATOR_RANDOM_ACCESS;
    tIterator.eContainerType = CONTAINER_VECTOR;

    return tIterator;
}

BAS_EXPORT T_Iterator basVectorInsert(T_Vector *ptVector, const T_Iterator tIterator, ...)
{
    assert(ptVector != NULL);
    assert(basIteratorIsValid(tIterator));
    assert(!basIteratorEqual(tIterator, basVectorREnd(ptVector)));
    assert(ptVector == (T_Vector *)tIterator.pvContainer);

    T_Iterator tNewIterator; //指向新插入元素的迭代器
    size_t nMoveBytes = 0;
    va_list varList;

    //事先计算要移动的字节数, 否则分配内存后会导致迭代器失效
    nMoveBytes = ptVector->pvEndPos - tIterator.tPos.pvBasicPos;

    //Vector已满, 重新分配内存
    if (_BAS_VECTOR_IS_FULL(ptVector))
    {
        if (_BAS_VECTOR_RESERVE(ptVector) != 0)
        {
            CONTAINER_LOG_ERROR("basVectorReserve failed");
            memset(&tNewIterator, 0, sizeof(T_Iterator));
            return tNewIterator;
        }
    }

    memcpy(&tNewIterator, &tIterator, sizeof(T_Iterator)); 
    tNewIterator.tPos.pvBasicPos = ptVector->pvEndPos - nMoveBytes;

    //移动元素
    memmove(tNewIterator.tPos.pvBasicPos + ptVector->tTypeInfo.nTypeSize,
            tNewIterator.tPos.pvBasicPos, nMoveBytes);

    //调整Vector尾部位置
    ptVector->pvEndPos += ptVector->tTypeInfo.nTypeSize;

    //拷贝新元素
    va_start(varList, tIterator); 
    if (_basContainerGetVaArgValue(&ptVector->tTypeInfo, tNewIterator.tPos.pvBasicPos, &varList) != 0)
    {
        CONTAINER_LOG_ERROR("_basContainerGetVaArgValue failed");
        memset(&tNewIterator, 0, sizeof(T_Iterator));
        return tNewIterator;
    }
    va_end(varList);

    return tNewIterator;
}

BAS_EXPORT T_Iterator basVectorErase(T_Vector *ptVector, const T_Iterator tIterator)
{
    assert(ptVector != NULL);
    assert(basIteratorIsValid(tIterator));
    assert(!basIteratorEqual(basVectorEnd(ptVector), tIterator));
    assert(ptVector == (T_Vector *)tIterator.pvContainer);

    size_t nMoveBytes = 0;

    //如果有销毁函数, 调用销毁函数
    if (ptVector->tTypeInfo.pfnDestroy != NULL)
    {
        ptVector->tTypeInfo.pfnDestroy(tIterator.tPos.pvBasicPos);
    }

    //计算要移动的字节数
    nMoveBytes = ptVector->pvEndPos - tIterator.tPos.pvBasicPos - ptVector->tTypeInfo.nTypeSize;
    //移动元素
    memmove(tIterator.tPos.pvBasicPos, 
            tIterator.tPos.pvBasicPos + ptVector->tTypeInfo.nTypeSize,
            nMoveBytes);

    //调整Vector尾部位置
    ptVector->pvEndPos -= ptVector->tTypeInfo.nTypeSize;

    return tIterator;
}

/**
 * @brief Vector额外的迭代器有效性检查
 * @see   basIteratorIsValid
 */
static bool _basVectorIteratorIsValid(const T_Iterator tIterator)
{
    T_Vector *ptVector = (T_Vector *)tIterator.pvContainer;

    if (tIterator.tPos.pvBasicPos > ptVector->pvEndPos ||
        tIterator.tPos.pvBasicPos < ptVector->pvStartPos - ptVector->tTypeInfo.nTypeSize)
    {
        return false;
    }

    return true;
}

/**
 *  @brief Vector实现的basIteratorGetValue 
 *  @see   basIteratorGetValue
 */
static void _basVectorIteratorGetValue(const T_Iterator tIterator, void *pvValue)
{
    memcpy(pvValue, tIterator.tPos.pvBasicPos,
           ((T_Vector *)tIterator.pvContainer)->tTypeInfo.nTypeSize);
}

/**
 * @brief Vector实现的basIteratorGetPointer
 * @see   basIteratorGetPointer
 */
static void *_basVectorIteratorGetPointer(const T_Iterator tIterator)
{
    return tIterator.tPos.pvBasicPos;
}

/**
 * @brief Vector实现的basIteratorSetValue
 * @see   basIteratorSetValue
 */
static void _basVectorIteratorSetValue(T_Iterator tIterator, const void * pvValue)
{
    memcpy(tIterator.tPos.pvBasicPos, pvValue,
           ((T_Vector *)tIterator.pvContainer)->tTypeInfo.nTypeSize);
}

/**
 * @brief Vector实现的basIteratorNext
 * @see   basIteratorNext
 */
static T_Iterator _basVectorIteratorNext(const T_Iterator tIterator)
{
    T_Iterator tIteratorNext;

    memcpy(&tIteratorNext, &tIterator, sizeof(T_Iterator));
    tIteratorNext.tPos.pvBasicPos += ((T_Vector *)tIteratorNext.pvContainer)->tTypeInfo.nTypeSize;

    assert(basIteratorIsValid(tIteratorNext));

    return tIteratorNext;
}

/**
 * @brief Vector实现的basIteratorPrev
 * @see   basIteratorPrev
 */
static T_Iterator _basVectorIteratorPrev(const T_Iterator tIterator)
{
    T_Iterator tIteratorPrev;

    memcpy(&tIteratorPrev, &tIterator, sizeof(T_Iterator));
    tIteratorPrev.tPos.pvBasicPos -= ((T_Vector *)tIteratorPrev.pvContainer)->tTypeInfo.nTypeSize;

    assert(basIteratorIsValid(tIteratorPrev));

    return tIteratorPrev;
}

/**
 * @brief Vector实现的basIteratorEqual
 * @see   basIteratorEqual
 */
static bool _basVectorIteratorEqual(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator)
{
    return tFirstIterator.tPos.pvBasicPos == tSecondIterator.tPos.pvBasicPos;
}

/**
 * @brief Vector实现的basIteratorLess
 * @see   basIteratorLess
 */
static bool _basVectorIteratorLess(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator)
{
    return tFirstIterator.tPos.pvBasicPos < tSecondIterator.tPos.pvBasicPos;
}

/**
 * @brief Vector实现的basIteratorNextN
 * @see   basIteratorNextN
 */
static T_Iterator _basVectorIteratorNextN(const T_Iterator tIterator, const size_t nCount)
{
    T_Iterator tIteratorNextN;

    memcpy(&tIteratorNextN, &tIterator, sizeof(T_Iterator));
    tIteratorNextN.tPos.pvBasicPos += ((T_Vector *)tIteratorNextN.pvContainer)->tTypeInfo.nTypeSize * nCount;
    
    assert(basIteratorIsValid(tIteratorNextN));

    return tIteratorNextN;
}

/**
 * @brief Vector实现的basIteratorPrevN
 * @see   basIteratorPrevN
 */
static T_Iterator _basVectorIteratorPrevN(const T_Iterator tIterator, const size_t nCount)
{
    T_Iterator tIteratorPrevN;

    memcpy(&tIteratorPrevN, &tIterator, sizeof(T_Iterator));
    tIteratorPrevN.tPos.pvBasicPos -= ((T_Vector *)tIteratorPrevN.pvContainer)->tTypeInfo.nTypeSize * nCount;

    assert(basIteratorIsValid(tIteratorPrevN));

    return tIteratorPrevN;
}

/**
 * @brief Vector实现的basIteratorMinus
 * @see   basIteratorMinus
 */
static int _basVectorIteratorMinus(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator)
{
    return (tFirstIterator.tPos.pvBasicPos - tSecondIterator.tPos.pvBasicPos) / 
           (int)((T_Vector *)tFirstIterator.pvContainer)->tTypeInfo.nTypeSize;
}

/** @} */
